---
title: 初始化Spring应用
---
## 创建项目

使用 IDEA 创建一个[Spring Boot](https://gitee.com/wkqgitee/my-study-project/tree/master/springboot)项目，将其展开，内容如下：

![image-20230214222535997](https://img.wkq.pub/hexo/image-20230214222535997.png)

可以看出，Spring Boot 是一个典型的 Maven 或 Gradle 项目结构，其中应用的源码放到了 "src/main/java" 中，测试代码放到了 "src/test/java" ；非 Java 的资源放到了 "src/main/resources" 中。在这个项目结构中，我们需要注意以下几点。

1. mvnm 和 mvnw.cmd : 这是 Maven 包装器（wrapper）脚本。借助这些脚本，即便机器上没有安装 Maven ，也可以构建项目。
2. pom.xml : 这是 Maven 的构建规范。
3. SpringBootApplication.java : 这是 Spring Boot 主类，它会启动该项目。
4. application.properties: 这个文件起初是空的，但是它为我们提供了指定配置属性的地方。
5. static： 在这个文件下，可以存放任意为浏览器提供服务的静态内容（图片、样式表、JavaScript等），该文件夹起始为空。
6. templates: 这个文件夹中存放用来渲染内容到浏览器的模板文件。这个文件夹初始是空的。
7. SpringbootApplicationTests.java: 这是一个简单的测试类，它能确保 Spring 应用上下文成功加载。

## Maven 的构建规范

```xml-dtd title='初始的Maven构建规范'
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>pub.wkq</groupId>
    <artifactId>springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot</name>
    <description>springboot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
```

在`<parent>`元素中，表明项目要以 `spring-boot-starter-parent`作为其父 POM。除了其它的一些功能外，这个父 POM 为 Spring 常用的一些库提供了依赖管理。对于父 POM 中所涵盖到的库，我们不需要指定它们的版本，因为他会通过父 POM 继承下来。

在`<dependencys>`元素下声明了 4 个依赖，除了 DevTools 依赖之外，其它的这些依赖的 artifiactId 上都有 starter 这个单词。Spring Boot  starter 依赖的特别指出在于它们本身并不包含库代码，而是传递性地拉取其它的库。这种 starter 依赖有以下几个好处。

* 构建文件会显著较小并且更易于管理，因为这样不必为所需的每个依赖库度声明依赖。
* 我们能够根据它们所提供的功能来思考依赖，而不是根据库的名称。
* 不必再担心库版本的问题。可以直接相信给定版本的 Spring Boot ,传递性引入的库的版本都是兼容的。

构建规范还包含一个 Spring Boot 插件。这个插件提供了一些重要的功能。

* 提供了一个 Maven goal，允许我们使用 Maven 来运行应用。
* 它会确保依赖的所有库都会包含在可执行 JAR 文件中，并且能够保证它们在运行时类路径下是可用的。

## 启动类

因为会以可运行 jar 文件的形式来运行应用，所以很重要的一点就是有一个主类，它会在 JAR 运行的时候被执行。

同时还需要有一个最小化的 Spring 配置，用来引导该应用。

这就是启动类的作用。

```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

//Spring Boot 应用
@SpringBootApplication
public class SpringbootApplication {
    public static void main(String[] args) {
        //运行应用
        SpringApplication.run(SpringbootApplication.class, args);
    }
}
```

`@SpringBootApplication`注解表明这是一个 Spring Boot  应用。

`@SpringBootApplication`注解是一个组合注解，组合了 3 个其它的注解。

* `@SpringBootConfiguration`： 将该类声明为配置类。这个注解其实是 `@Configuration`注解的特殊形式。
* `@EnableAutoConfiguration`: 启用 Spring Boot 的自动配置。这个注解会告诉 Spring Boot 自动配置它认为我们会用到的组件。
* `@ComponentScan`:启用组件扫描。这样我们能够通过像 `@Component`、`@Controller`、`@Service`、`@Repository` 这样的注解声明其它类，Spring 会自动发现它们并将它们注册到 Spring 应用上下文中。

启动类另一个重要的地方就是它的 main 方法。这是 JAR 文件执行的时候要运行的方法。

这个 main() 方法会调用 SpringApplication 中静态的 run() 方法，后者会真正执行应用的引导过程，也就是创建 Spring 应用上下文。

传递给 run() 的两个参数中，一个是配置类，另一个是命令行参数。尽管传递给 run() 的配置类不一定要和启动类相同，但这是最便利和最典型的做法。

## 测试应用

测试是软件开发的重要组成部分。我们可用通过在命令行中构建应用、运行测试，从而实现项目的手动测试：

```sh
./mvnw package
...
java -jar .\target\springboot-0.0.1-SNAPSHOT.jar
```

或者，使用 Spring Boot 的 Maven 插件：

```sh
./mvnw spring-boot:run
```

但是，自动测试会更加一致和可重复。

```java title='Spring Boot 有一个初始的测试类。'
@SpringBootTest //Spring Boot 测试
class SpringbootApplicationTests {
	
    //测试方法
    @Test 
    void contextLoads() {
        System.out.println("执行自动测试" );
    }

}
```

默认测试类中的内容并不多：这个类中只有一个空的测试方法，但它会执行必要的检查，确保 Spring 应用上下文成功加载。



`@SpringBootTest` 会告诉 JUnit 启动测试的时候要加上 Spring Boot 的功能。像 `@SpringBootApplication`一样，`@SpringBootTest`也是一个组合注解，会为测试加载 Spring应用上下文，它本身使用了 `@ExtendWith(SpringExtension.class),`从而能够将 Spring 的测试功能添加到 JUnit 5 中。

要在命令行运行这个测试类及其它任意的测试类，我们都可以使用如下的 Maven 指令：

```sh
./mvnw test
```



